/**
 * Copyright (c) 2015-2017, Winter Lau (javayou@gmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.oschina.j2cache;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import jline.console.ConsoleReader;

/**
 * 缓存测试入口
 * 
 * @author Winter Lau(javayou@gmail.com)
 */
public class J2CacheCmd {

	private static long TTL = 0;

	public static void main(String[] args) throws IOException {
		J2Cache j2Cache = new J2Cache();
		CacheChannel cache = j2Cache.getChannel(); // 获取 J2Cache 操作接口
		ConsoleReader reader = new ConsoleReader();

		String line;

		do {
			try {
				line = reader.readLine("> ");

				if (line == null || line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit")) {
					break;
				}

				String[] cmds = line.split(" ");
				if ("get".equalsIgnoreCase(cmds[0])) {
					CacheObject obj = cache.get(cmds[1], cmds[2]); // 从缓存读取数据
					System.out.printf("[%s,%s,L%d]=>%s(TTL:%d)\n", obj.getRegion(), obj.getKey(), obj.getLevel(),
							obj.getValue(), TTL);
				} else if ("mget".equalsIgnoreCase(cmds[0])) {
					List<String> keys = Arrays.stream(cmds).skip(2).collect(Collectors.toList());
					Map<String, CacheObject> values = cache.get(cmds[1], keys); // 批量获取缓存数据
					if (values != null && values.size() > 0) {
						values.forEach((key, obj) -> System.out.printf("[%s,%s,L%d]=>%s(TTL:%d)\n", obj.getRegion(),
								obj.getKey(), obj.getLevel(), obj.getValue(), TTL));
					} else {
						System.out.println("none!");
					}
				} else if ("set".equalsIgnoreCase(cmds[0])) {
					if ("null".equalsIgnoreCase(cmds[3])) {
						cmds[3] = null;
					}
					cache.set(cmds[1], cmds[2], cmds[3], TTL, true); // 数据写入缓存
					System.out.printf("[%s,%s]<=%s(TTL:%d)\n", cmds[1], cmds[2], cmds[3], TTL);
				} else if ("mset".equalsIgnoreCase(cmds[0])) {
					String region = cmds[1];
					Map<String, Object> objs = new HashMap<>();
					for (int i = 2; i < cmds.length; i++) {
						String[] obj = cmds[i].split(":");
						if ("null".equalsIgnoreCase(obj[1])) {
							obj[1] = null;
						}
						objs.put(obj[0], obj[1]);
					}
					cache.set(cmds[1], objs, TTL, true); // 批量写入数据到缓存
					objs.forEach((k, v) -> System.out.printf("[%s,%s]<=%s(TTL:%d)\n", region, k, v, TTL));
				} else if ("evict".equalsIgnoreCase(cmds[0])) {
					String[] keys = Arrays.stream(cmds).skip(2).toArray(String[]::new);
					cache.evict(cmds[1], keys); // 清除某个缓存数据
					for (String key : keys) {
						System.out.printf("[%s,%s]=>null\n", cmds[1], key);
					}
				} else if ("clear".equalsIgnoreCase(cmds[0])) {
					cache.clear(cmds[1]); // 清除某个缓存区域的数据
					System.out.printf("Cache [%s] clear.\n", cmds[1]);
				} else if ("regions".equalsIgnoreCase(cmds[0])) {
					System.out.println("Regions:");
					cache.regions().forEach(r -> System.out.println(r));
				} else if ("keys".equalsIgnoreCase(cmds[0])) {
					Collection<String> keys = cache.keys(cmds[1]); // 获得某个缓存区域的所有
																	// key
					if (keys != null) {
						System.out.printf("[%s:keys] => (%s)(TTL:%d)\n", cmds[1], String.join(",", keys), TTL);
					} else {
						System.out.println("none!");
					}
				} else if ("ttl".equalsIgnoreCase(cmds[0])) {
					if (cmds.length == 1) {
						System.out.printf("TTL => %d\n", TTL);
					} else {
						TTL = Long.parseLong(cmds[1]);
						System.out.printf("TTL <= %d\n", TTL);
					}
				} else if ("help".equalsIgnoreCase(cmds[0])) {
					printHelp();
				} else {
					System.out.println("Unknown command.");
					printHelp();
				}
			} catch (ArrayIndexOutOfBoundsException e) {
				System.out.println("Wrong arguments.");
				printHelp();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} while (true);

		cache.close(); // 关闭 J2Cache 缓存
		reader.shutdown();

		System.exit(0);
	}

	private static void printHelp() {
		System.out.println("Usage: [cmd] region key [value]");
		System.out.println("cmd: get/mget/set/mset/evict/regions/keys/clear/ttl/quit/exit/help");
		System.out.println("Examples:");
		System.out.println("\tset region key value");
		System.out.println("\tget region key");
		System.out.println("\tmget region key1 key2 key3");
		System.out.println("\tmset region key1:value1 key2:value2 key3:value3");
		System.out.println("\tkeys region");
		System.out.println("\tttl [seconds]");
		System.out.println("\texit");
	}

}